/*
 *  CESceneManager.h
 *  LID Library
 *
 *  Created by Alexander Trutchenko on 09/11/11.
 *  Copyright 2011 League of Independent Developers. All rights reserved.
 *
 */

#ifndef __CE_SceneManager_h__
#define __CE_SceneManager_h__


#include <string>
#include <map>
#include <deque>

namespace cocos2d 
{
class CCScene;
}

namespace cocosext {

////////////////////////////////////////////////////////
//
/** CESceneManagerItem
 *  
*/
////////////////////////////////////////////////////////

class CESceneManagerItem
{
public:
	CESceneManagerItem() {;}
	virtual ~CESceneManagerItem() {;}

public:
	virtual cocos2d::CCScene* createScene() = 0;

}; // CESceneManager


////////////////////////////////////////////////////////
//
/** CESimpleSceneManagerItem
 *  
*/
////////////////////////////////////////////////////////

template<typename T>
class CESimpleSceneManagerItem: public CESceneManagerItem
{
public:
	CESimpleSceneManagerItem() {;}
	virtual ~CESimpleSceneManagerItem() {;}

public:
	virtual cocos2d::CCScene* createScene() { return T::scene(); }

}; // CESimpleSceneManager

////////////////////////////////////////////////////////
//
/** CEScenePathInfo
 *  
*/
////////////////////////////////////////////////////////

struct CEScenePathInfo
{
	std::string key;
	bool wasReplaced;
	bool resetScene;

private: 
	CEScenePathInfo();

public:
	CEScenePathInfo(const std::string& key_, bool wasReplaced_): key(key_), wasReplaced(wasReplaced_), resetScene(false) {;}
};

////////////////////////////////////////////////////////
//
/** CESceneManager
 *  
*/
////////////////////////////////////////////////////////

class CESceneManager
{ 
	typedef std::map<std::string, CESceneManagerItem*>	CEFactoryItems;
	typedef std::deque<CEScenePathInfo> CEScenePath;

private:
	CEFactoryItems _items;
	CEScenePath _scenePath;
	std::string _currentSceneKey;


private:
	static CESceneManager* s_instance;

private:
	CESceneManager() {;}
	~CESceneManager();

public:
	static CESceneManager* sharedSceneManager();
	static void pvt_remove();

public:
// Main interface	
	void setFactoryItemForKey(CESceneManagerItem* item, const std::string& key);
	void replaceScene(const std::string& key, bool clearResources = true);
//	void replaceSceneWithClearingScenePath(const std::string& key, bool clearScenePath = false, const std::string lastKeyToClear = "");
	void pushScene(const std::string& key);
	void returnToPreviousScene();
	void runWithScene(const std::string& key);
	const std::string& currentSceneKey() const { return _currentSceneKey; }
	void resetAllScenes();
	void resetCurrentScene(bool clearResources = false);

private:
	cocos2d::CCScene* createSceneForKey(const std::string& key) const;
	
}; //CESceneManager

}; // end namespace cocosext

#endif // __CE_SceneManager_h__
